/**
 * @file clientHandler.cpp
 * @author your name (you@domain.com)
 * @brief 
 * @version 0.1
 * @date 2024-07-20
 * 
 * @copyright Copyright (c) 2024
 * 
 */

#include "httpHandler.h"
#include "basic/trace.h"
#include "httpSvr/request.h"

#include <thread>
#include <unistd.h>
#include <sys/socket.h>

namespace wheels
{

int HttpHandler::OnHandleClient(int cliFd, std::string clientAddr)
{
    trace_info("client: %s\n", clientAddr.c_str());
    if (m_count.load() + 1 >= MaxLinkNum)
    {
        trace_err("client number too much:%d\n", m_count.load());
        return -1;
    }

    std::thread t(&HttpHandler::HandleRequest, this, cliFd, clientAddr);
    t.detach();
    return 0;
}

void HttpHandler::HandleRequest(int cliFd, std::string clientAddr)
{
    std::unique_ptr<int, void(*)(int *)> fileCloser(&cliFd, [](int *fd) { close(*fd); });
    
    Request req(cliFd, clientAddr);
    while(true)
    {
        std::string line = GetLine(cliFd);
        if (line.empty())
        {
            trace_err("get line fail\n");
            return;
        }

        if (line.size() == 1)
        {
            trace_info("header end !!!\n");
            break;
        }

        trace_info("head:%s\n", line.c_str());
    }
}

std::string HttpHandler::GetLine(int fd)
{
    std::string line;
    const int max_line_num = 1024;
    int count = 0;
    char c = '\0';
    while(count < max_line_num && c != '\n')
    {
        int n = recv(fd, &c, 1, 0);
        if (n != 1)
        {
            trace_err("recv err:%s\n", strerror(errno));
            return std::string();
        }

        if (c == '\r')
        {
            n = recv(fd, &c, 1, MSG_PEEK);
            if (n == 1 && c == '\n')
            {
                recv(fd, &c, 1, 0);
                line.push_back(c);
                return line;
            } else {
                return std::string();
            }
        }
        line.push_back(c);
    }
    return std::string();
}

} // namespace wheels
